﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TouchDriver.Data;

namespace TouchDriver
{
    public partial class AlignForm : Form
    {
        private ComReader reader = ComReader.GetInstance();
        private Point[] points = new Point[5];
        private Point[] rawPoints = new Point[10];
        private int targetPos = 0;

        public float K = 0;
        public float B = 0;

        public AlignForm()
        {
            InitializeComponent();
            Init();
        }

        private void Init()
        {
            this.KeyDown += new KeyEventHandler(AlignForm_KeyDown);
            this.Shown += new EventHandler(AlignForm_Shown);
            pictureBox.MouseClick += new MouseEventHandler(pictureBox_MouseClick);

            reader.MouseClickEvent += new ComReader.MouseClickHandler(reader_MouseClickEvent);
            reader.Start();
        }

        void reader_MouseClickEvent(Location loc)
        {
            //if (GetMousePosIndex(loc) == targetPos % 5)
            //{
            //    rawPoints[targetPos] = new Point(loc.x, loc.y);
            //    Mouse.LeftClick(points[targetPos % 5].X, points[targetPos % 5].Y);
            //}

            rawPoints[targetPos] = new Point(loc.x, loc.y);
            Mouse.LeftClick(points[targetPos % 5].X, points[targetPos % 5].Y);
        }

        //private int GetMousePosIndex(Location loc)
        //{
        //    if(loc.x >= points[0].X-pictureBox.Width/2 && loc.x <= points[0].X+pictureBox.Width/2 &&
        //        loc.y >= points[0].Y-pictureBox.Height/2 && loc.y <= points[0].Y+pictureBox.Height/2)
        //    {
        //        return 0;
        //    }
        //    else if (loc.x >= points[1].X - pictureBox.Width / 2 && loc.x <= points[1].X + pictureBox.Width / 2 &&
        //        loc.y >= points[1].Y - pictureBox.Height / 2 && loc.y <= points[1].Y + pictureBox.Height / 2)
        //    {
        //        return 1;
        //    }
        //    else if (loc.x >= points[2].X - pictureBox.Width / 2 && loc.x <= points[2].X + pictureBox.Width / 2 &&
        //        loc.y >= points[2].Y - pictureBox.Height / 2 && loc.y <= points[2].Y + pictureBox.Height / 2)
        //    {
        //        return 2;
        //    }
        //    else if (loc.x >= points[3].X - pictureBox.Width / 2 && loc.x <= points[3].X + pictureBox.Width / 2 &&
        //        loc.y >= points[3].Y - pictureBox.Height / 2 && loc.y <= points[3].Y + pictureBox.Height / 2)
        //    {
        //        return 3;
        //    }
        //    else if (loc.x >= points[4].X - pictureBox.Width / 2 && loc.x <= points[4].X + pictureBox.Width / 2 &&
        //        loc.y >= points[4].Y - pictureBox.Height / 2 && loc.y <= points[4].Y + pictureBox.Height / 2)
        //    {
        //        return 4;
        //    }
        //    else
        //    {
        //        return -1;
        //    }
        //}

        void pictureBox_MouseClick(object sender, MouseEventArgs e)
        {
            if (targetPos < 10)
            {
                targetPos++;
                pictureBox.Location = points[targetPos % 5];

                if (targetPos == 10)
                {
                    //计算转换公式
                    CalcFactor();

                    this.DialogResult = DialogResult.Yes;
                    this.Dispose();
                }
            }
        }

        void AlignForm_Shown(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Maximized;

            int x = this.Width;
            int y = this.Height;

            int w = pictureBox.Width/2;
            int h = pictureBox.Height/2;

            points[0] = new Point(100 - w, 100 - h);
            points[1] = new Point(x-100 - w, 100 - h);
            points[2] = new Point(x-100 - w, y-100 - h);
            points[3] = new Point(100 -w , y-100 - h);
            points[4] = new Point(x/2 - w, y/2 - h);

            targetPos = 0;
            pictureBox.Location = points[targetPos];
            pictureBox.Visible = true;
        }

        void AlignForm_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode == Keys.Escape)
            {
                DialogResult result = MessageBox.Show("Cancel Align?", "Warning", MessageBoxButtons.YesNo);
                if(result == DialogResult.Yes)
                {
                    this.DialogResult = DialogResult.Cancel;
                    this.Dispose();
                }
            }
        }

        PointF GetFactor(Point raw, Point screen)
        {
            PointF result = new PointF();

            //raw.X * K + B = screen.X;
            //raw.Y * K + B = screen.Y;

            //raw.Y * raw.X * K + raw.Y * B = screen.X * raw.Y;
            //raw.X * raw.Y * K + raw.X * B = screen.Y * raw.X;


            //(raw.Y - raw.X)*B = screen.X * raw.Y - screen.Y * raw.X;

            if (raw.X == raw.Y)
                result.X = result.Y = 0;
            else
            {
                result.Y = ((float)(screen.X * raw.Y - screen.Y * raw.X)) / (float)((raw.Y - raw.X));
                result.X = ((float)(screen.X - result.Y)) / (float)raw.X;
            }
            return result;
        }

        private void CalcFactor()
        {
            PointF [] factors = new PointF[10];
            for (int i = 0; i < 10; ++i)
            {
                factors[i] = GetFactor(points[i % 5], rawPoints[i]);
            }

            K = 0;
            for (int i = 0; i < 10; ++i)
            {
                K += factors[i].X;
                B += factors[i].Y;
            }

            K /= 10;
            B /= 10;
        }
    }
}
